/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2024 INRIA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*!\file NonSmoothDrivers.h
  This file provides all generic functions (drivers), interfaces to the different formulations
  for Non-Smooth Problems available in Numerics.

  \todo solve_qp does not exist

  Use fc3d tools.
*/
#ifndef NonSmoothSolvers_H
#define NonSmoothSolvers_H

#include "SiconosConfig.h"

/* #include "mlcp_cst.h" */
/* #include "MCP_cst.h" */
/* #include "NCP_cst.h" */
/* #include "lcp_cst.h" */
/* #include "relay_cst.h" */
/* #include "Friction_cst.h" */
/* #include "VI_cst.h" */
/* #include "AVI_cst.h" */
/* #include "SOCLCP_cst.h" */
//#include "VariationalInequality.h"
//#include "VariationalInequality_Solvers.h"
//#include "SecondOrderConeLinearComplementarityProblem.h"
/* #include "SOCLCP_Solvers.h" */
/* #include "Relay_Solvers.h" */
/* #include "LCP_Solvers.h" */
/* #include "AVI_Solvers.h" */
/* #include "MLCP_Solvers.h" */
/* #include "NCP_Solvers.h" */
/* #include "MCP_Solvers.h" */
//#include "SolverOptions.h"
#include "NumericsFwd.h"
//#include "MixedComplementarityProblem.h"
/* #include "fc2d_Solvers.h" */
/* #include "fc3d_Solvers.h" */
/* #include "gfc3d_Solvers.h" */
//#include "GenericMechanical_Solvers.h"

//#include "NonSmoothNewton.h"

#if defined(__cplusplus) && !defined(BUILD_AS_CPP)
extern "C" {
#endif

/**
    General interface to solvers for Linear Complementarity Problems

    \param[in] problem the LinearComplementarityProblem structure which handles the problem
   (M,q) \param[in,out] z a n-vector of doubles which contains the solution of the problem.
    \param[in,out] w a n-vector of doubles which contains the solution of the problem.
    \param[in,out] options structure used to define the solver(s) and their parameters
    \return info termination value
    - 0 : successful
    - >0 : otherwise see each solver for more information about the log info
*/
int linearComplementarity_driver(LinearComplementarityProblem *problem, double *z, double *w,
                                 SolverOptions *options);

/**
   General interface to solver for MLCP problems

   \param[in] problem the MixedLinearComplementarityProblem structure which handles the problem
   (M,q) \param[in,out] z a m+n-vector of doubles which contains the solution of the problem.
   \param[in,out] w a m+n-vector of doubles which contains the solution of the problem.
   \param[in,out] options structure used to define the solver(s) and their parameters
   \return info termination value,

   - 0 : successful
   - >0 : otherwise see each solver for more information about the log info
   \todo Sizing the regularization parameter and apply it only on null diagnal term
*/
int mlcp_driver(MixedLinearComplementarityProblem *problem, double *z, double *w,
                SolverOptions *options);

/**
   General interface to solvers for friction-contact 2D problem

   \param[in] problem the structure which handles the Friction-Contact problem
   \param[in,out] reaction global vector (n)
   \param[in,out] velocity global vector (n)
   \param[in,out] options structure used to define the solver(s) and their parameters
   \return result (0 if successful otherwise 1).
*/
int fc2d_driver(FrictionContactProblem *problem, double *reaction, double *velocity,
                SolverOptions *options);

/**
    General interface to solvers for friction-contact 3D problem

    \param[in] problem the structure which handles the Friction-Contact problem
    \param[in,out] reaction global vector (n)
    \param[in,out] velocity global vector (n)
    \param[in,out] options structure used to define the solver(s) and their parameters
    \return result (0 if successful otherwise 1).
*/
int fc3d_driver(FrictionContactProblem *problem, double *reaction, double *velocity,
                SolverOptions *options);

/**
   General interface to solvers for rolling friction-contact 3D problem

   \param[in] problem the structure which handles the Friction-Contact problem
   \param[in,out] reaction global vector (n)
   \param[in,out] velocity global vector (n)
   \param[in,out] options structure used to define the solver(s) and their parameters
   \return result (0 if successful otherwise 1).
*/
int rolling_fc3d_driver(RollingFrictionContactProblem *problem, double *reaction,
                        double *velocity, SolverOptions *options);

/**
   General interface to solvers for rolling friction-contact 2D problem

   \param[in] problem the structure which handles the Friction-Contact problem
   \param[in,out] reaction global vector (n)
   \param[in,out] velocity global vector (n)
   \param[in,out] options structure used to define the solver(s) and their parameters
   \return result (0 if successful otherwise 1).
*/
int rolling_fc2d_driver(RollingFrictionContactProblem *problem, double *reaction,
                        double *velocity, SolverOptions *options);

/**
   General interface to solvers for global friction-contact 2D problem

   \param[in] problem the structure which handles the Friction-Contact problem
   \param[in,out] reaction global vector (n)
   \param[in,out] velocity global vector (n)
   \param[in,out] globalVelocity global vector
   \param[in,out] options structure used to define the solver(s) and their parameters
   \return result (0 if successful otherwise 1).
*/
int gfc2d_driver(GlobalFrictionContactProblem *problem, double *reaction, double *velocity,
                 double *globalVelocity, SolverOptions *options);

/**
   General interface to solvers for global friction-contact 3D problem

   \param[in] problem the structure which handles the Friction-Contact problem
   \param[in,out] reaction global vector (n)
   \param[in,out] velocity global vector (n)
   \param[in,out] globalVelocity global vector
   \param[in,out] options structure used to define the solver(s) and their parameters
   \return result (0 if successful otherwise 1).
*/
int gfc3d_driver(GlobalFrictionContactProblem *problem, double *reaction, double *velocity,
                 double *globalVelocity, SolverOptions *options);

/**
   General interface to solvers for global rolling friction-contact 3D problem

   \param[in] problem the structure which handles the Friction-Contact problem
   \param[in,out] reaction global vector (n)
   \param[in,out] velocity global vector (n)
   \param[in,out] options structure used to define the solver(s) and their parameters
   \return result (0 if successful otherwise 1).
*/
int g_rolling_fc3d_driver(GlobalRollingFrictionContactProblem *problem, double *reaction,
                          double *velocity, double *globalVelocity, SolverOptions *options);

/**
    General interface to solvers for friction-contact 3D problem

    \param[in] problem the structure which handles the Friction-Contact problem
    \param[in,out] x global vector (n)
    \param[in,out] w global vector (n)
    \param[in,out] options structure used to define the solver(s) and their parameters
    \return result (0 if successful otherwise 1).
 */
int variationalInequality_driver(VariationalInequality *problem, double *x, double *w,
                                 SolverOptions *options);

/**
    General interface to solvers for Affine Variational Inequalities (AVI)

    \param[in] problem the AffineVariationalInequalities structure which handles the problem
   (M,q) \param[in,out] z a n-vector of doubles which contains the solution of the problem.
    \param[in,out] w a n-vector of doubles which contains the solution of the problem.
    \param[in,out] options structure used to define the solver(s) and their parameters
    \return info termination value
    - 0 : successful
    - >0 : otherwise see each solver for more information about the log info
*/
int avi_driver(AffineVariationalInequalities *problem, double *z, double *w,
               SolverOptions *options);

/**
   General interface to solver for MCP problems

   \param[in] problem the MixedComplementarityProblem_old structure which handles the problem
   \param[in,out] z a m+n-vector of doubles which contains the solution of the problem.
   \param[in,out] w a m+n-vector of doubles which contains the solution of the problem.
   \param[in,out] options structure used to define the solver(s) and its(their) parameters
   \return info termination value  0 : successful, else error.
*/
int mcp_old_driver(MixedComplementarityProblem_old *problem, double *z, double *w,
                   SolverOptions *options);

/**
   General interface to solver for MCP problems -- new version

   \param[in] problem the MixedComplementarityProblem structure which handles the problem
   \param[in,out] z a m+n-vector of doubles which contains the solution of the problem.
   \param[in,out] w a m+n-vector of doubles which contains the solution of the problem.
   \param[in,out] options structure used to define the solver(s) and its(their) parameters
   \return info termination value  0 : successful, else error.
*/
int mcp_driver(MixedComplementarityProblem *problem, double *z, double *w,
               SolverOptions *options);

/**
   General interface to solver for NCP problems

   \param[in] problem the NonlinearComplementarityProblem structure which handles the problem
   \param[in,out] z a n-vector of doubles which contains the solution of the problem.
   \param[in,out] F a n-vector of doubles which contains value of the function evaluated at the
   solution of the problem. \param[in,out] options structure used to define the solver(s) and
   its(their) parameters \return info termination value  0 : successful, else error
*/
int ncp_driver(NonlinearComplementarityProblem *problem, double *z, double *F,
               SolverOptions *options);

/**
   General interface to solvers for SOCLCP problem

   \param[in] problem the structure which handles the Friction-Contact problem
   \param[in,out] r global vector (n)
   \param[in,out] v global vector (n)
   \param[in,out] options structure used to define the solver(s) and their parameters
   \return result (0 if successful otherwise 1).
*/
int soclcp_driver(SecondOrderConeLinearComplementarityProblem *problem, double *r, double *v,
                  SolverOptions *options);

/**
   LMGC interface to solvers for friction-contact 3D problem

   \param[in,out] reaction global vector (nc*3)
   \param[in,out] velocity global vector (nc*3)
   \param[in] q global vector (nc*3)
   \param[in] mu global vector (nc)
   \param[in] W the block matrix in coordinate format
   \param[in] row block row indices
   \param[in] column block column indices
   \param[in] nc number of contacts
   \param[in] nb number of blocks
   \param[in] solver_id id an int to be mapped to actual solver in Numerics
   \param[in] tolerance threshold used to validate the solution: if the error is less than this
   value, the solution is accepted \param[in] itermax the maximum number of iteration
   \param[in] verbose level 0 : nothing, 1: mid level 2: high level
   \param[in] outputFile outputFile option 0 : nothing 1 : dat file 2: FCLIB HDF5 file if FCLIB
   is found \param[in] freq_output \param[in] ndof the numbe of dof in the dynamical systems
   involved in contact (for output in file.) \return result (0 if successful otherwise 1).

*/
int fc3d_LmgcDriver(double *reaction, double *velocity, double *q, double *mu, double *W,
                    unsigned int *row, unsigned int *column, unsigned int nc, unsigned int nb,
                    int solver_id, double tolerance, int itermax, int verbose, int outputFile,
                    int freq_output, int ndof);

/**
   LMGC interface to solvers for global friction-contact 3D problem

   \param[in,out] reaction global vector (nc*3)
   \param[in,out] velocity global vector (nc*3)
   \param[in,out] globalVelocity global velocity vector (n)
   \param[in] q global vector (n)
   \param[in] b global vector (nc*3)
   \param[in] mu global vector (nc)
   \param[in] Mdata the sparse matrix in coordinate format
   \param[in] nzM number of non zeros in Mdata
   \param[in] rowM  row indices of M
   \param[in] colM  column indices of M
   \param[in] Hdata the sparse matrix in coordinate format
   \param[in] nzH number of non zeros in Hdata
   \param[in] rowH  row indices of H
   \param[in] colH  column indices of H
   \param[in] n size of global velocity
   \param[in] nc number of contacts
   \param[in] solver_id id an int to be mapped to actual solver in Numerics
   \param[in] isize sive of integer parameters array
   \param[in] iparam integer parameters array
   \param[in] dsize sive of double parameters array
   \param[in] dparam double parameters array
   \param[in] verbose level 0 : nothing, 1: mid level 2: high level
   \param[in] outputFile outputFile option 0 : nothing 1 : C file , 1 :  dat file 3: FCLIB HDF5
   file if FCLIB is found \param[in] freq_output \return result (0 if successful otherwise 1).

 */
int gfc3d_LmgcDriver(double *reaction, double *velocity, double *globalVelocity, double *q,
                     double *b, double *mu, double *Mdata, unsigned int nzM,
                     unsigned int *rowM, unsigned int *colM, double *Hdata, unsigned int nzH,
                     unsigned int *rowH, unsigned int *colH, unsigned int n, unsigned int nc,
                     int solver_id, int isize, int *iparam, int dsize, double *dparam,
                     int verbose, int outputFile, int freq_output);

/**
   General interface to solver for relay problems

   \param[in] problem the RelayProblem structure which handles the problem (M,q)
   \param[in,out] z a n-vector of doubles which contains the solution of the problem.
   \param[in,out] w a n-vector of doubles which contains the solution of the problem.
   \param[in,out] options structure used to define the solver(s) and its (their) parameters
   \return info termination value

   - 0 : successful
   - >0 : otherwise see each solver for more information about the log info
*/
int relay_driver(RelayProblem *problem, double *z, double *w, SolverOptions *options);

#if defined(__cplusplus) && !defined(BUILD_AS_CPP)
}
#endif

#endif
